// Learn TypeScript:
//  - https://docs.cocos.com/creator/manual/en/scripting/typescript.html
// Learn Attribute:
//  - https://docs.cocos.com/creator/manual/en/scripting/reference/attributes.html
// Learn life-cycle callbacks:
//  - https://docs.cocos.com/creator/manual/en/scripting/life-cycle-callbacks.html

import { PLAYER_STATE } from "./Constant";

const { ccclass, property } = cc._decorator;
@ccclass
export default class PlayerCtrl extends cc.Component {
    static EventType = {
        GENERATE_INK: "generate_ink",
    }

    @property(cc.RigidBody)
    body: cc.RigidBody = null;

    private isLeftKeyDown: boolean = false;
    private isRightKeyDown: boolean = false;
    private enableJump: boolean = false;
    private horizontalForce: number = 2000;
    private verticalImpulse: number = 1000;

    //生成墨汁的间隔
    private limitInterval: number = 0.05;
    private timeDelta: number = 0;
    private state: PLAYER_STATE = PLAYER_STATE.NONE;

    onEnable() {
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
        cc.systemEvent.on(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
    }

    protected onDisable(): void {
        cc.systemEvent.off(cc.SystemEvent.EventType.KEY_DOWN, this.onKeyDown, this);
        cc.systemEvent.off(cc.SystemEvent.EventType.KEY_UP, this.onKeyUp, this);
    }

    private onKeyDown(event: cc.Event.EventKeyboard) {
        switch (event.keyCode) {
            case cc.macro.KEY.left: this.isLeftKeyDown = true;
                break;
            case cc.macro.KEY.right: this.isRightKeyDown = true;
                break;
            case cc.macro.KEY.space: this.enableJump = true;
                break;
        }
    }

    private onKeyUp(event: cc.Event.EventKeyboard) {
        switch (event.keyCode) {
            case cc.macro.KEY.left: this.isLeftKeyDown = false;
                break;
            case cc.macro.KEY.right: this.isRightKeyDown = false;
                break;
            case cc.macro.KEY.space: this.enableJump = false;
                break;
        }
    }

    protected update(dt: number): void {
        this.timeDelta += dt;

        if (this.isLeftKeyDown) {
            this.moveLeft();
        } else if (this.isRightKeyDown) {
            this.moveRight();
        }

        if (this.enableJump) {
            this.enableJump = false;
            this.jump();
        }
    }

    jump() {
        this.body.applyLinearImpulse(cc.v2(0, this.verticalImpulse), cc.Vec2.ZERO_R, true);
    }

    moveLeft() {
        this.body.applyForceToCenter(cc.v2(-this.horizontalForce, 0), true);
    }

    moveRight() {
        this.body.applyForceToCenter(cc.v2(this.horizontalForce, 0), true);
    }

    // 只在两个碰撞体开始接触时被调用一次
    onBeginContact(contact, selfCollider, otherCollider) {
        // cc.log("onBeginContact");
        var worldManifold = contact.getWorldManifold();
        // var points = worldManifold.points;
        // var normal = worldManifold.normal;
        this.onContact(worldManifold.points);
    }

    // 只在两个碰撞体结束接触时被调用一次
    onEndContact(contact, selfCollider, otherCollider) {
        // cc.log("onEndContact");
    }

    // 每次将要处理碰撞体接触逻辑时被调用
    onPreSolve(contact, selfCollider, otherCollider) {
        // cc.log("onPreSolve");
    }

    // 每次处理完碰撞体接触逻辑时被调用
    onPostSolve(contact, selfCollider, otherCollider) {
        // cc.log("onPostSolve");
        var worldManifold = contact.getWorldManifold();
        // var points = worldManifold.points;
        // var normal = worldManifold.normal;
        this.onContact(worldManifold.points);
    }

    private onContact(points: cc.Vec2[]) {
        if (this.timeDelta >= this.limitInterval && this.body.linearVelocity.len() > 0) {
            this.timeDelta = 0;
            this.node.emit(PlayerCtrl.EventType.GENERATE_INK, points);
        }
    }
}
